package com.lhy.noed;

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @description: 获取数据库结构信息
 * @author: 李汇远
 */
public class DbInfo {

    // 数据库schema
    private final String dbName;

    // 数据库表名
    private List<String> tbNames;

    // 数据库表名到列名的映射
    private Map<String, List<String>> colNames = new HashMap<>();

    // 数据库表对应的jsonObject
    private Map<String, JSONObject> entity = new HashMap<>();

    /**
     * 数据库表结构
     * Map<String,ArrayList<Map<String,String>>>
     * {
     * tbName:[
     * {name:'字段名称', type:'数据类型' is_key:'是主键吗？'},...
     * ], ...
     * }
     */
    private Map<String, ArrayList<HashMap<String, String>>> tbStructure;

    // 字段信息的map
    public static final String NAME = "name";
    public static final String TYPE = "col_type";
    public static final String IS_KEY = "is_key";

    // 判断字段是否是主键
    public static final String IS_KEY_YES = "TRUE";
    public static final String IS_KEY_NO = "FALSE";

    // spring对jdbc的封装
    JdbcTemplate jdbcTemplate;

    /**
     * 初始化数据库表信息
     *
     * @param jdbcTemplate
     */
    public DbInfo(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        // 获取数据库名
        dbName = jdbcTemplate.queryForObject("select database()", String.class);
        Objects.requireNonNull(dbName);
        System.out.println("[GzExecute] database:" + dbName);
        // 获取当前数据库所有的表名称
        String sql = "select TABLE_NAME FROM information_schema.TABLES WHERE table_schema like '%s'";
        tbNames = jdbcTemplate.queryForList(String.format(sql, dbName), String.class);
        if (tbNames.isEmpty())
            throw new RuntimeException(String.format("数据库(%s)的表格为空", dbName));
        System.out.println("[GzExecute] tables:" + tbNames);
        // 获取每个数据库表的结构信息
        tbStructure = tbNames.parallelStream()
                .collect(Collectors.toMap(String::toString
                        , tbName -> (ArrayList) jdbcTemplate.queryForList(
                                String.format("select COLUMN_NAME as %s, DATA_TYPE as %s, (CASE COLUMN_KEY WHEN 'PRI' THEN '%s' ELSE '%s' END) as %s  from information_schema.COLUMNS WHERE TABLE_SCHEMA like '%s' and TABLE_NAME like '%s'"
                                        , NAME, TYPE, IS_KEY_YES, IS_KEY_NO, IS_KEY, dbName, tbName))));

        // 获取列名信息和实体类信息
        for (Map.Entry entry : tbStructure.entrySet()) {
            ArrayList<Object> list = (ArrayList<Object>) entry.getValue();
            List list1 = list.parallelStream().map(res -> ((Map) res).get(NAME)).collect(Collectors.toList());
            colNames.put((String) entry.getKey(), list1);
            JSONObject jsonObject = new JSONObject();
            for (String col : (List<String>) list1) {
                jsonObject.put(col, "");
            }
            entity.put((String) entry.getKey(), jsonObject);
        }

    }

    /**
     * 获取数据库表名
     *
     * @return
     */
    public List<String> getTableNames() {
        return new ArrayList<>(tbNames);
    }

    /**
     * 获取数据库表结构
     *
     * @return
     */
    public Map<String, ArrayList<HashMap<String, String>>> getTableStructure() {
        return tbStructure;
    }

    public Map<String, List<String>> getColNames() {
        return colNames;
    }

    /**
     * 根据表名获取实体类的JSONObject,默认值取 ""
     *
     * @param tableName
     * @return
     */
    public JSONObject getEntity(String tableName) {
        return entity.get(tableName);
    }


}
